//
//  WeatherDetailsTableViewCell.swift
//  SwiftWeather
//
//  Created by shen on 2023/8/28.
//

import UIKit
import Combine

class WeatherDetailsCellViewModel {
    // MARK: Properties

    @Published private var weather: CurrentWeather?

    var type: WeatherDetails {
        return detailsType
    }

    var title: String {
        detailsType.rawValue
    }

    var valuePublisher: AnyPublisher<Double, Never> {
        $weather
            .compactMap { $0 }
            .map { [weak self] currentWeather in
                switch self?.detailsType {
                case .wind:
                    return currentWeather.windKph ?? 0
                case .humidity:
                    return Double(currentWeather.humidity ?? 0)
                case .pressure:
                    return currentWeather.pressureIn ?? 0
                case .visibility:
                    return currentWeather.visKM ?? 0
                case .uvIndex:
                    return currentWeather.uv ?? 0
                case .none:
                    return 0
                }
            }
            .eraseToAnyPublisher()
    }

    private let detailsType: WeatherDetails

    // MARK: - Initialization

    init(weather: CurrentWeather?, detailsType: WeatherDetails) {
        self.weather = weather
        self.detailsType = detailsType
    }
}

class WeatherDetailsTableViewCell: BaseTableViewCell, ViewModelable {
    typealias ViewModel = WeatherDetailsCellViewModel

    // MARK: Properties

    var viewModel: ViewModel! {
        didSet {
            iconImageView.image = viewModel.type.icon
            titleLabel.text = "\(viewModel.title)"

            viewModel.valuePublisher
                .sink { [weak self] value in
                    guard let self else { return }
                    self.displayValueLabel(with: value, for: self.viewModel.type)
                }
                .store(in: &cancellables)
        }
    }

    private var cancellables = Set<AnyCancellable>()

    // MARK: - Views

    private lazy var iconImageView = UIImageView(
        tintColor: Resources.Colors.darkText,
        contentMode: .scaleAspectFit
    )

    private lazy var titleLabel = UILabel(
        textColor: Resources.Colors.darkText,
        font: Resources.Fonts.system(size: 14, weight: .semibold)
    )

    private lazy var valueLabel = UILabel(
        textColor: Resources.Colors.darkText,
        font: Resources.Fonts.system(size: 13, weight: .light)
    )

    // MARK: - Methods

    override func setupViews() {
        contentView.addSubview(iconImageView, useAutoLayout: true)
        contentView.addSubview(titleLabel, useAutoLayout: true)
        contentView.addSubview(valueLabel, useAutoLayout: true)
    }

    override func constraintViews() {
        NSLayoutConstraint.activate([
            iconImageView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 8),
            iconImageView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 20),
            iconImageView.widthAnchor.constraint(equalToConstant: 30),
            iconImageView.heightAnchor.constraint(equalTo: iconImageView.widthAnchor),

            titleLabel.leadingAnchor.constraint(equalTo: iconImageView.trailingAnchor, constant: 20),
            titleLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),

            valueLabel.leadingAnchor.constraint(greaterThanOrEqualTo: titleLabel.trailingAnchor, constant: 20),
            valueLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -20),
            valueLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor)
        ])

        let iconBottomConstraint = iconImageView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -8)
        iconBottomConstraint.priority = .defaultLow
        iconBottomConstraint.isActive = true
    }
}

// MARK: - Private methods

private extension WeatherDetailsTableViewCell {
    func displayValueLabel(with value: Double, for detailsType: WeatherDetails) {
        var text = String()

        switch detailsType {
        case .wind:
            text = "\(value) Km/h"
        case .humidity:
            text = "\(value.toRoundedInt)%"
        case .pressure:
            text = "\(value.toRoundedInt)º"
        case .visibility:
            text = "\(value) Km"
        case .uvIndex:
            text = "\(value.toRoundedInt)"
        }

        valueLabel.text = text
    }
}
